﻿using System;
using System.Collections.Generic;

namespace DrDimsLib.CoreSDK.Functionality
{
    using System.IO;
    using System.Linq;
    using System.Text;
    using CLRExtension;

    public abstract class IOUtilBase
    {
        /* C:\Users\yxieguodong\Desktop\ */
        protected string CheckIO(string fPath)
        {
            string rsPath = fPath;
            if (string.IsNullOrEmpty(fPath))
            {
                rsPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            }
            return rsPath;
        }
        /// <summary>
        /// 递归扫描文件夹 获取文件列表*所有* V2 by 丁诚昊
        /// </summary>
        /// <param name="PathRoot"> 起始路径 </param>
        /// <returns> 字符串地址集合 </returns>
        public IEnumerable<StreamInfo> ScanFolderV2(string PathRoot,
            bool isRecursivelySearch = true)
        {
            string RealName = CheckIO(PathRoot);
            List<StreamInfo> info = new List<StreamInfo>();

            // 1.清理当前线程本职工作 - 加载 ./*.files 文件清单
            var files = Directory.GetFiles(RealName);
            files.OrderByDescending(item => {
                var ptr2File = new FileInfo(item);
                return ptr2File.Length;
            }).ToList().ForEach(item =>
            {
                var ptr2File = new FileInfo(item);
                info.Add(new StreamInfo(item));
            });
            // 2.压入系统堆栈 递归搜索子目录序列
            var dires = Directory.GetDirectories(RealName).OrderBy(item => {
                /* 按照文件夹子文件数量进行排序 */
                return new DirectoryInfo(item).GetFiles().Count();
            }).ToList();
            foreach (var item in dires) {
                var sub = new DirectoryInfo(item);
                if (sub.Exists)
                {
                    #region 开启递归
                    if (isRecursivelySearch)
                    {
                        var recursiveTree = ScanFolderV2(sub.FullName,true);
                        if(recursiveTree != null)
                            info.AddRange(recursiveTree);
                    }
                    else
                    {
                        // 添加当前目录中的SubDir到 info序列
                        info.Add(new StreamInfo(sub.FullName));
                    }
                    #endregion
                }
            };
            return info;
        }
        /* 1.主函数[Core] 扫描系统路径,按文件扩展名进行分类汇总 */
        protected IEnumerable<string> ScanFolder(string FolderPath,
            params string[] FExtTypes)
        {
            if (FExtTypes.Length == 0 || FExtTypes == null)
                FExtTypes = AnalyzibleFiles.ToArray();

            var realPath = CheckIO(FolderPath);
            // 读取路径下所有文件 
            string[] allFiles = Directory.GetFiles(realPath);
            var filterGroup = from pFile in allFiles
                              orderby Path.GetExtension(pFile).FirstOrDefault()
                              group pFile by Path.GetExtension(pFile) into g
                              select g;
            filterGroup.ToList().ForEach(g =>
            {
                CacheHash.Value.Add(g.Key, new List<string>(g.Count()));
            });
            // 根据文件扩展名进行 分类汇总
            List<string> ptr = new List<string>();
            allFiles.ToList().ForEach(f =>
            {
                var DICT = CacheHash.Value;
                var ext = Path.GetExtension(f);
                if (DICT.Keys.Contains(ext))
                {
                    List<string> docker = DICT[ext] as List<string>;
                    docker.Add(f);
                    ptr.AddRange(docker);
                }
            });
            // 钩子函数
            // ScanFile();
            return ptr;
        }
        /* 2.按类型进行文件分类汇总 */
        protected internal Int32 ScanFile()
        {
            int fCounts = 0;
            foreach (var ext in AnalyzibleFiles)
            {
                // 只读取 过滤列表内 的扩展名
                var types = from g in CacheHash.Value
                            where g.Key.EndsWith(ext.ToLower())
                            orderby g.Key.Count() descending
                            select g.Value;
                foreach (IEnumerable<string> typeFiles in types)
                {
                    // 调用文件内容读取
                    Console.WriteLine("\n" + typeFiles.FirstOrDefault() + " 数量[{0}] ", typeFiles.Count());
                    Console.WriteLine("Top L1 ---> " + typeFiles.FirstOrDefault());
                    foreach (string ExactFile in typeFiles)
                    {
                        //钩子函数
                        ScanLines(ExactFile);
                    }
                    fCounts++;
                }
            }
            return fCounts;
        }
        /* 3.逐行扫描正则匹配 */
        protected internal Int32 ScanLines(string ExactFile)
        {
            /* 2.抓取其中的Url */
            string line = string.Empty;
            using (var sr = new StreamReader(ExactFile))
            {
                Console.WriteLine("[文件`{0}`] ---> ", Path.GetFileName(ExactFile));
                // 只读取首页4行
                int preReadLine = 0, maxCharsOfLine = 56;
                while ((line = sr.ReadLine()) != null)
                {
                    preReadLine++;
                    if (string.IsNullOrWhiteSpace(line))
                        continue;
                    // 匹配文本中的所有URL地址
                    var url = reExp.Match(line).Value;
                    if (!string.IsNullOrEmpty(url))
                    {
                        if (url.Length >= maxCharsOfLine)
                        {
                            url = url.Substring(0, url.LastIndexOf("/") + 1) + "[Url]过长截断...";
                        }
                        Console.WriteLine("\t\t在[{0}]行抓取到 URL --> `{1}`", preReadLine, url);
                    }
                }
            }
            // 返回文件比特大小
            using (var fs = new FileStream(ExactFile, FileMode.Open))
            {
                var bLen = Convert.ToInt32(fs.Length);
                Console.WriteLine("bytes[{0}]比特", bLen);
                return bLen;
            }
        }
        /// <summary>
        /// 懒加载 LazyT<缓存字典>
        /// </summary>
        internal Lazy<Dictionary<string, IEnumerable<string>>> CacheHash =
            new Lazy<Dictionary<string, IEnumerable<string>>>(() =>
            {
                return new Dictionary<string, IEnumerable<string>>();
            });
        /* 预设变量属性包装器 */
        public IEnumerable<string> AnalyzibleFiles
        {
            get
            {
                return new string[] { "TXT", "SQL", "HTML" };
            }
        }
        protected System.Text.RegularExpressions.Regex reExp;
        protected readonly Encoding Encoder = Encoding.UTF8;
    }
}
